package cn.edu.scau.cmi.ema.util;

import cn.edu.scau.cmi.ema.base.CmiPagination;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;

import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;


// 离线查询，有些暂时不知道是SQL还是HQL，后期还是应该分开
public class CmiSqlUtil {

//	@Transactional
//	这个方法用于统计符合页面传递过来的请求条件数量，和下面的方法同样的作用。
	public static String createCountHql(CmiPagination page, Class entityClass) {
		String entityName = entityClass.getName();
		StringBuilder sqlStringBuilder = new StringBuilder();
		sqlStringBuilder.append("select count(myEntity) from " + entityName + " myEntity");
		String appendConditionsClause = appendCriterias(page, entityClass);
		sqlStringBuilder = sqlStringBuilder.append(appendConditionsClause);
		return sqlStringBuilder.toString();
	}

	// 这个方法用于统计符合页面传递过来的请求条件数量，和上面的的方法同样的作用，暂时使用上面的这个方法。
	public static DetachedCriteria createDetachedCriteria(CmiPagination cmiPagination, Class entityClass) {
		DetachedCriteria detachedCriteria = DetachedCriteria.forClass(entityClass);

		Map<String, String> basicPropertyCriteriaMap = cmiPagination.getBasicPropertyCriteriaMap();
		Set<Entry<String, String>> basicPropertyCriteriaMapEntrySet = basicPropertyCriteriaMap.entrySet();
		for (Entry<String, String> enrty : basicPropertyCriteriaMapEntrySet) {
			String propertyName = enrty.getKey();
			propertyName = propertyName.substring(0, 1).toLowerCase() + propertyName.substring(1);
			String propertyValue = enrty.getValue();
			if (propertyValue == null || "".equals(propertyValue.trim())) {
				continue;
			}
//			TODO 待测试   detachedCriteria.add(Restriction.                                            )
//			detachedCriteria.add(Restrictions.eq(propertyName, propertyValue.trim()));

//			如果是String类型，使用模糊查巡，如果是其他类型，就使用精确查询。
			try {
				if (entityClass.getDeclaredField(propertyName).getType().getName().equals("java.lang.String")) {
					detachedCriteria.add(
							Restrictions.sqlRestriction(propertyName + " like \'%" + propertyValue.trim() + "%\'"));
				} else {
					detachedCriteria
							.add(Restrictions.sqlRestriction(propertyName + " = \'" + propertyValue.trim() + "\'"));
				}
			} catch (NoSuchFieldException | SecurityException e) {
				e.printStackTrace();
			}
		}
		return detachedCriteria;
	}

//	@Transactional
	public static String createSelectHql(CmiPagination page, Class entityClass) {
		String entityName = entityClass.getName();
		StringBuilder sqlStringBuilder = new StringBuilder();
		sqlStringBuilder.append("select myEntity from " + entityName + " myEntity");
		String appendConditionsClause = appendCriterias(page, entityClass);
		sqlStringBuilder = sqlStringBuilder.append(appendConditionsClause);
		return sqlStringBuilder.toString();
	}

//	@Transactional
	private static String appendCriterias(CmiPagination page, Class entityClass) {
		StringBuilder hqlStringBuilder = new StringBuilder();

		Map<String, String> basicPropertyCriteriaMap = page.getBasicPropertyCriteriaMap();
		Set<Entry<String, String>> basicPropertyCriteriaMapEntrySet = basicPropertyCriteriaMap.entrySet();

//		基本属性部分：
		for (Entry<String, String> enrty : basicPropertyCriteriaMapEntrySet) {
			String basicPropertyName = enrty.getKey();
			basicPropertyName = basicPropertyName.substring(0, 1).toLowerCase() + basicPropertyName.substring(1);
			String basicPropertyValue = enrty.getValue();

			// 如果没有值，就取下一个的属性
			if (basicPropertyValue == null || "".equals(basicPropertyValue.trim())) {
				continue;
			}

			if (hqlStringBuilder.length() > 0) {
				hqlStringBuilder.append(" and ");
			}
			try {
				if (entityClass.getDeclaredField(basicPropertyName).getType().getName().equals("java.lang.String")) {
					hqlStringBuilder.append(basicPropertyName + "  like \'%" + basicPropertyValue.trim() + "%\'");
				}
//				添加待测试

				else if (entityClass.getDeclaredField(basicPropertyName).getType().getName().equals("java.lang.Boolean")) {
					hqlStringBuilder.append(basicPropertyName + "  = " + basicPropertyValue.trim());
				}
				else {
					hqlStringBuilder.append(basicPropertyName + "  = "  + basicPropertyValue.trim() );
				}
			} catch (NoSuchFieldException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (SecurityException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

		if (hqlStringBuilder.length() > 0) {
			hqlStringBuilder.insert(0, " where ");
			return hqlStringBuilder.toString();
		} else {
			return "";
		}
	}
}
